package com.example.emailWeb.ntru.encrypt;

import com.example.emailWeb.ntru.polynomial.IntegerPolynomial;
import com.example.emailWeb.ntru.polynomial.LongPolynomial;

public class NtruProxyServer {
    int N,p,q;
    boolean sparse;
    NtruProxyParameters params;
    public IntegerPolynomial R,invertR,B,Rkab,CA,CB; //A发来的R，B发来的B; R就是r1;
    boolean isGetB = false,isGetR = false,isCA = false;

    public NtruProxyServer(NtruProxyParameters param) {
        this.params = param;
        init();
    }

    public NtruProxyServer() {
        this.params = NtruProxyParameters.APR2011_439;
        init();
    }

    public NtruProxyServer(IntegerPolynomial r, IntegerPolynomial b) {
        this.params = NtruProxyParameters.APR2011_439;
        init();
        R = r;
        B = b;
        receiveR(R);
        receiveB(B);
    }

    /**
     * 通过rkab构造，只进行CA转CB的操作
     * @param rkab
     */
    public NtruProxyServer(IntegerPolynomial rkab) {
        this.params = NtruProxyParameters.APR2011_439;
        init();
        // 只进行CA转CB，
        Rkab = rkab;
    }

    /**
     * 必须先调用receiveR、receiveB，才能调用getRkab()
     * @return
     */
    public IntegerPolynomial getRkab() {
        return Rkab;
    }

    private void init(){
        this.N = params.N;
        this.p = params.p;
        this.q = params.q;
        this.sparse = params.sparse;
    }
    public void receiveR(IntegerPolynomial R){
        this.R = R.clone();
        isGetR = true;
        if(isGetB&&isGetR){
            getInvertR();//生成R的逆invertR
            IntegerPolynomial BClone = B;
            Rkab = B.mult(invertR,q);
            Rkab.center0(q);
        }
    }
    public void receiveB(IntegerPolynomial B){
        this.B = B.clone();
        isGetB= true;
        if(isGetB&&isGetR){
            getInvertR();
            IntegerPolynomial BClone = B;
            Rkab = B.mult(invertR,q);
            Rkab.center0(q);
        }
    }
    public void receiveCA(IntegerPolynomial CA){
        this.CA = CA.clone();
    }

    //计算R模q的逆,invertR
    public void getInvertR(){
        IntegerPolynomial invertFq = R.invertFq(q);
        if(invertFq == null){
            System.out.println("A发来的R没有模q的逆；");
        }
        this.invertR = invertFq;
    }

    /**
     * 把A发来的CA转成CB，把CB发给B；
     */
    public LongPolynomial CA2CB(LongPolynomial CA){
        if(Rkab == null){
            System.out.println("RKab还没有生成");
        }
//        IntegerPolynomial CB;
//        CB = CA.mult(Rkab);
        LongPolynomial CB = CA.mult(Rkab.toLongPolynomial());

        return CB;
    }

    public IntegerPolynomial CA2CB(IntegerPolynomial CA){
        if(Rkab == null){
            System.out.println("RKab还没有生成");
        }
//        IntegerPolynomial CB;
//        CB = CA.mult(Rkab);
        IntegerPolynomial CB = CA.mult(Rkab);

        return CB;
    }

    @Override
    public String toString() {
        return "NtruProxyServer{" +
                "N=" + N +
                ", p=" + p +
                ", q=" + q +
                ", sparse=" + sparse +
                ", params=" + params +
                ", R=" + R +
                ", invertR=" + invertR +
                ", B=" + B +
                ", Rkab=" + Rkab +
                ", CA=" + CA +
                ", CB=" + CB +
                ", isGetB=" + isGetB +
                ", isGetR=" + isGetR +
                ", isCA=" + isCA +
                '}';
    }
}
